Skip to content

feat(fiber): harden type safety, add scheduler + showcase#49

Open
MarcelOlsen wants to merge 32 commits into
masterfrom
feat/fiber-type-safety
Open

feat(fiber): harden type safety, add scheduler + showcase#49
MarcelOlsen wants to merge 32 commits into
masterfrom
feat/fiber-type-safety

Conversation

@MarcelOlsen

Copy link
Copy Markdown
Owner

Summary

This PR hardens the fiber reconciler for maximal type safety and minimal unsafe casts, adds a real binary min-heap scheduler, wires the concurrent rendering path, and ships an interactive browser showcase.

Key Changes

🔒 Type Safety

  • Centralised unsafe-cast boundary (src/fiber/bitwise.ts): all Lane/Lanes/Flags conversions live in one file; zero stray as number elsewhere.
  • Simplified branded types: Lanes = Lane alias resolves impossible Lane ⊄ Lanes incompatibilities at every function boundary while keeping branding.
  • HookEffectTag = number instead of branded union: bitwise OR on effect tags naturally produces number.
  • Widened function signatures (laneIncludes, isLanesEmpty, lanesToSchedulerPriority) accept both Lane and Lanes.
  • Compile-time enforcement: tests/fiber/types.typecheck.ts with @ts-expect-error directives that fail on regression.

⚡ Scheduler

  • Binary min-heap (src/fiber/minHeap.ts): real siftUp/siftDown replacing push + sort (O(log n) vs O(n log n)).
  • performConcurrentWorkOnRoot + renderRootConcurrent: concurrent path is now wired and functional.
  • ensureRootIsScheduled: routes sync lanes directly, non-sync lanes via scheduleCallback.

🧪 Tests

  • 9 new test modules: bitwise.test.ts, minHeap.test.ts, typeGuards.test.ts, lanes.test.ts, scheduler.test.ts, resumability.test.ts, hydration.test.ts, fiberUtils.test.ts, commitIntegration.test.ts.
  • Total: 473 pass, 0 fail, 1,526 expect() calls across 38 files.

🎨 Showcase

  • examples/interactive-showcase/: live Vite-powered demo covering all 7 public APIs (useState, useEffect/useRef, useMemo/useCallback, createContext/useContext, createPortal, Fragment, useReducer).

📚 Docs

  • Updated README to reflect Phase 13 (Fiber Reconciler + Type Safety Hardening) complete.

Verification

# Tests
bun test

# Type check
bun run typecheck   # 0 errors

Breaking Changes

None — all changes are internal refactoring + additive features.

Remove the example/ directory and .trae/ rules. Update CI workflow,
biome config, tsconfig, and package.json for fiber architecture.
Add Fiber, FiberRoot, Hook, Effect types with WorkTag, Lane, and Flags
branded types. Update core/types.ts to export hook-related types and
remove old VDOMInstance.
Add type predicates for fiber tags (isHostComponent, isFunctionComponent,
etc.) and assertion helpers for the fiber tree.
- isUpdatedQueue now vlaidates all five UpdateQueue<S> fields
- isHookState now checks all five Hook properties
- setDynamicProperty / getDynamicProperty, both now reject __proto__, constructor, and prototype keys by throwing an error, preventing prototype pollution
- isFiberRoot now validates types: containerInfo must be a non-null object
- assertTextProps error message now correctly names the actual source (pendingProps or memoizedProps) based on which one was used
- isHookState now validates that baseQueue, queue, and next are each either null or an object
- isEffectState now validates that tag is a number, create is a function, destroy is undefined or a function, deps is null or an array, and next is null or an object.
…eanup

  - Convert boolean-returning fiber tag helpers to real TS type predicates
  - Add stateNode !== null checks to host fiber type guards
  - Validate full shapes in isHookState, isEffectState, isUpdateQueue, and
    isMemoComponent instead of only checking key existence
  - Add isUpdate type guard for Update<S> shape validation
  - Tighten isTextProps to validate nodeValue is string or number
  - Tighten isFiberRoot to verify property types, not just presence
  - Guard isHTMLElement, isHTMLInputElement, isElement, isTextNode against
    missing DOM globals for SSR safety
  - Fix assertTextProps error message to report correct prop source
  - Reject prototype-polluting keys in setDynamicProperty/getDynamicProperty
  - Add JSDoc warnings to getMemoizedState/assertMemoizedState about unchecked casts
  - Rename mergeLanesUnsafe/intersectLanesUnsafe/removeLanesUnsafe to
    mergeLanes/intersectLanes/removeLanes
  - Move Host* type aliases above their corresponding type guard functions
Add Lane type operations for priority scheduling: mergeLanes,
removeLanes, includesSomeLane, and lane management utilities.
Add time-slicing scheduler with priority levels and shouldYield.
Add WIP tree management with prepareFreshStack and
createWorkInProgressFiber for double-buffering.
Add createFiber, createFiberFromElement, createFiberRoot, and
createWorkInProgress for constructing fiber nodes from elements.
Add findHostParent, findHostSibling, collectHostChildren for tree
traversal. Add effect creation, collection, and passive effect
scheduling.
Add reconcileChildFibers and mountChildFibers implementing the
two-pass key-based diffing algorithm for efficient child updates.
Add useState, useEffect, useRef, useMemo, useCallback, useReducer,
and useContext hooks on the fiber architecture. Update context module
to use fiber tree traversal for value lookup.
Add beginWork for tag-specific fiber processing during render phase.
Add completeWork for DOM node creation and effect flag bubbling.
Add commitPlacement, commitUpdate, commitDeletion for DOM mutations.
Add commitRoot orchestrating the three commit sub-phases: before
mutation, mutation, and layout.
Refactor event delegation to work with fiber nodes. Add registerFiber,
unregisterFiber, and fiber-based event routing while removing old
VDOM-based event handling.
Add performSyncWorkOnRoot, scheduleUpdateOnFiber, createRoot,
updateContainer, and flushSync. Add fiber/index.ts re-exporting
all public fiber APIs.
Add hydrateRoot and enterHydrationState for client-side hydration.
Add serializeFiberTree and dehydrateRoot for state serialization
and resumability.
Update core/index.ts, MiniReact.ts, and jsx-runtime to export
fiber-based implementations. Remove old dom-renderer, fragments,
hooks, and reconciler modules.
Add fiber-specific tests (rendering, reconciliation, hooks, effects,
commit, context, events, portals, memo, refs, errors, internals).
Update existing integration tests for fiber-based API. Remove old
reconciler tests.
- Centralise all unsafe Lane/Lanes/Flags casts into src/fiber/bitwise.ts
- Implement binary min-heap scheduler (O(log n)) in src/fiber/minHeap.ts
- Wire concurrent rendering path (performConcurrentWorkOnRoot + renderRootConcurrent)
- Simplify branded types: Lanes = Lane alias, HookEffectTag = number
- Add 9 new test modules: bitwise, minHeap, typeGuards, lanes, scheduler,
  resumability, hydration, fiberUtils, commitIntegration
- Add compile-time type enforcement test (types.typecheck.ts)
- Export useMemo / useCallback / useReducer from index.ts
- Build interactive browser showcase (examples/interactive-showcase/)
- Update README: 473 tests, zero type errors, Phase 13 complete

Typecheck: 0 errors
Tests: 473 pass, 0 fail, 1,526 expects across 38 files
@MarcelOlsen
MarcelOlsen force-pushed the feat/fiber-type-safety branch from 4fc41ff to cbc2b93 Compare May 2, 2026 12:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant